/*
 * =====================================================================================
 *
 *       Filename:  compareProcs.c
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  17.4.2013 20:06:31
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  YOUR NAME (), 
 *   Organization:  
 *
 * =====================================================================================
 */

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

#include "compareProcs.h"


#define MAX_PID 32768
#define MAX_PID_LEN 6


const char *FILENAME = "ibpLsOut.ibp";


int readPidFromFile(const char *filename)
{
    FILE *f = fopen(filename, "r");
    if(f == NULL) {
        fprintf(stderr, "Nepodarilo se otevrit soubor %s\n", filename);
        return 0;
    }

    int c;
    char pidStr[MAX_PID_LEN];
    int i = 0;
    while((c = getc(f)) != EOF) {
        if(isspace(c))
            continue;
        
        if(isdigit(c) && i < (MAX_PID_LEN-1)) {
            pidStr[i] = c;
            i++;
        }
        else {
            fclose(f);
            return 0;
        }
    }
    
    pidStr[i] = '\0';
    fclose(f);
    return atoi(pidStr);
}

int isInProc(int wantedPid)
{
    struct stat st;
    char path[16];
    memset(path, 0, sizeof(path));
    snprintf(path, sizeof(path), "/proc/%d", wantedPid);
    if(stat(path, &st) < 0) {
        return 0;    
    }

    return 1;
}

int isInPs(int wantedPid)
{
    if((wantedPid <= 0) || (wantedPid > MAX_PID))
        return 0;

    char cmd[50];
    snprintf(cmd, sizeof(cmd), "ps --no-headers -o pid -p %d > ./%s", wantedPid, FILENAME);
    system(cmd);
    
    int ret = 0;
    int pid = readPidFromFile(FILENAME);
    if((pid > 0) && (pid == wantedPid)) {
        ret = 1;
    }

    remove(FILENAME);
    return ret;
}


int getAllSuspicious(int suspicious[], int len, tCompareType compType)
{   
    // Na zacatek pole vynulujeme
    memset(suspicious, 0, sizeof(suspicious));
    
    // Vytvoreni bufferu
    char *buf = (char *)malloc(MAX_PID_LEN * sizeof(char));
    if(buf == NULL) {
        fprintf(stderr, "Chyba pri alokaci pole\n");
        return -2;
    }

    // Zapis zajisti, ze se v modulu nactou vsechny procesy
    int fdWrite = open("/proc/ibpAllProcs", O_WRONLY );
    if(fdWrite < 0) {
        fprintf(stderr, "Nepodarilo se otevrit soubor: /proc/ibpAllProcs pro zapis\n");
        return -1;
    }
    int taskListCount = write(fdWrite, (void*)buf, MAX_PID_LEN);
    close(fdWrite);
    
    // Ziskani vsech procesu z modulu
    int suspCount = 0;
    int l;
    int fdRead;
    int pid = 0;
    int find = 0;
    for(int i = 0; i < taskListCount; i++) {
        // Otevreni souboru
        fdRead = open("/proc/ibpAllProcs", O_RDONLY);
        if(fdRead < 0) {
            fprintf(stderr, "Chyba pri otevirani souboru pro cteni\n");
            suspCount = -1;
            break;
        }

        // Nacteni pid
        if((l = read(fdRead, buf, MAX_PID_LEN)) < 0) {
            fprintf(stderr, "Chyba pri cteni souboru /proc/ibpAllProcs\n");
            close(fdRead);
            suspCount = -1;
            break;
        }
        pid = atoi(buf);

        find = 0;
        switch(compType) {
            case BY_PROC:
                find = ! isInProc(pid);
                break;
            case BY_PS:
                find = ! isInPs(pid);
                if(find)
                    printf("Nalezeno pid %d\n", pid);
                break;
            case ALL:
                find = ! isInProc(pid);
                if(!find)
                    find = ! isInPs(pid);
                break;
        }
        //printf("V task list nacteno %d, pid: %s\n", l, buf);
        
        if(find) {
            if(i > len) {
                fprintf(stderr, "Vsechny podezrele procesy se nevesli do pole\n");
                close(fdRead);
                suspCount = -3;
                break;
            }

            suspicious[suspCount] = pid;
            suspCount++;
        }

        close(fdRead);
    }

   return suspCount;
}


void printInfo(int suspicious[], int len)
{
    FILE *fRead;
    FILE *fWrite;
    int c;

    printf("Bylo nalezone %d podezrelych procesu", len);
    for(int i = 0; i < len; i++) {
        printf("\n");
        printf("Podezrely proces %d - pid: %d ", i, suspicious[i]);

        
        fWrite = fopen("/proc/ibpProcInfo.ibp", "w");
        if(fWrite == NULL) {
            continue;
        }
        fprintf(fWrite, "%05d", suspicious[i]);
        fclose(fWrite);

        fRead = fopen("/proc/ibpProcInfo.ibp", "r");
        if(fRead == NULL) {
            continue;
        }

        printf("nazev: ");
        while((c = getc(fRead)) != EOF) {
            printf("%c", c);
        }
        fclose(fRead);
    }
    printf("\n");
}
